package chances.epg.data.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import chances.epg.commons.log.EpgLogFactory;
import chances.epg.data.PageBean;
import chances.epg.entity.biz.BizPosition;
import chances.epg.entity.biz.BizPositionItem;

@Service
@EnableScheduling
public class BizPositionService extends EpgService {
	private static Logger logger = EpgLogFactory.getSystemLogger();
	
	private Map<String,BizPosition> positionList;
	
	public BizPositionService() {
		positionList = new ConcurrentHashMap<String,BizPosition>();
	}
	
	@PostConstruct
	public void init(){
		this.loadAllPositions();
	}
	
	/**
	 * 后台定时刷新，装载推荐位数据到内存中.
	 */
	@SuppressWarnings("unchecked")
	@Scheduled(fixedDelay=1000*60*2)
	public void loadAllPositions() {
		logger.debug("Loaing biz positions...");
		Map<String,BizPosition> result = new ConcurrentHashMap<String,BizPosition>();
		List<BizPosition> allPositions = (List<BizPosition>)this.queryForList("getAllBizPositions");
		for (BizPosition position : allPositions) {
			result.put(position.getCode(), position);
		}
		
		Map<String,Object> paramsMap = new HashMap<String,Object>();
		paramsMap.put("curTime", new Date());
		
		PageBean pageBean = new PageBean(1000);
		List<BizPositionItem> items = (List<BizPositionItem>)this.queryForList("getAllValidBizPositionItems", paramsMap, 0, pageBean);
		this.fillBizPosition(result, items);
		
		if(pageBean.getPageCount() > 1) {
			//从第二页开始
			for (int i = 2; i <= pageBean.getPageCount(); i++) {
				pageBean.setCurrentPage(i);
				items = (List<BizPositionItem>)this.queryForList("getAllValidBizPositionItems", paramsMap, 0, pageBean);
				this.fillBizPosition(result, items);
			}
		}
		
		Map<String,BizPosition> old = this.positionList;
		this.positionList = result;
		old.clear();
		old = null;
	}
	
	/**
	 * 
	 * @param code
	 * @return
	 */
	public BizPosition getBizPositionByCode(String code) {
		BizPosition pos = this.positionList.get(code);
		if(pos != null) {
			return pos;
		}
		
		pos = this.findBizPositionByCode(code);
		if(pos != null) {
			List<BizPositionItem> items = this.findBizPositionItemsByCode(code);
			pos.addItems(items);
		}
		
		return pos;
	}
	
	@SuppressWarnings("unchecked")
	public BizPositionItem getPositionItemById(Long itemId) {
		Map<String,Object> paramsMap = new HashMap<String,Object>();
		paramsMap.put("itemId", itemId);
		try{
		    List<BizPositionItem> result = (List<BizPositionItem>)this.queryForList("getPosisionItemById",paramsMap);
			return result.size() > 0 ? result.get(0) : null;
		}finally{
			paramsMap.clear();
			paramsMap = null;
		}
	}
	
	/**
	 * 将推荐位元素添加到推荐位中.
	 * @param result
	 * @param items
	 */
	private void fillBizPosition(Map<String,BizPosition> result,List<BizPositionItem> items) {
		for (BizPositionItem item : items) {
			BizPosition pos = result.get(item.getPositionCode());
			if(pos != null) {
				pos.addItem(item);
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private BizPosition findBizPositionByCode(String code) {
		Map<String,Object> paramsMap = new HashMap<String,Object>();
		paramsMap.put("code", code);
		try{
			List<BizPosition> result = (List<BizPosition>)this.queryForList("getBizPositionByCode",paramsMap);
			return result.size() > 0 ? result.get(0) : null;
		}finally{
			paramsMap.clear();
			paramsMap = null;
		}
	}
	
	@SuppressWarnings("unchecked")
	private List<BizPositionItem> findBizPositionItemsByCode(String positionCode) {
		Map<String,Object> paramsMap = new HashMap<String,Object>();
		paramsMap.put("positionCode", positionCode);
		try{
			return (List<BizPositionItem>)this.queryForList("getBizPositionItemsByCode",paramsMap);
		}finally{
			paramsMap.clear();
			paramsMap = null;
		}
	}
}
